package com.yfp.machine.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import com.yfp.common.core.constant.EmqxConstants;
import com.yfp.emqx.MqttSendClient;
import com.yfp.machine.domain.Combo;
import com.yfp.machine.domain.DeviceCurrentComboPlanRoad;
import com.yfp.machine.domain.ImgResource;
import com.yfp.machine.domain.MachineRoad;
import com.yfp.machine.domain.dto.ComboDetailsDto;
import com.yfp.machine.domain.dto.MachineComboDetailsDto;
import com.yfp.machine.domain.dto.RoadInfoDto;
import com.yfp.machine.mapper.ImgResourceMapper;
import com.yfp.machine.mapper.MachineRoadMapper;
import com.yfp.machine.service.ComboService;
import com.yfp.machine.service.DeviceCurrentComboPlanRoadService;
import com.yfp.machine.service.MachineRoadService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;


/**
 * (MachineRoad)表服务实现类
 *
 *
 * @since 2023-12-14 14:32:01
 */
@Service("machineRoadService")
@Slf4j
public class MachineRoadServiceImpl implements MachineRoadService {
    @Resource
    private MachineRoadMapper machineRoadMapper;

    @Resource
    private ComboService comboService;

    @Resource
    private MqttSendClient matchSendClient;

    @Resource
    DeviceCurrentComboPlanRoadService deviceCurrentComboPlanRoadService;

    @Resource
    ImgResourceMapper imgResourceMapper;

    /**
     * 通过ID查询单条数据
     *
     * @param machineId 主键
     * @return 实例对象
     */
    @Override
    public MachineRoad queryById(String machineId) {
        return this.machineRoadMapper.queryById(machineId);
    }

    /**
     * 分页查询
     *
     * @param machineRoad 筛选条件
     * @param pageRequest 分页对象
     * @return 查询结果
     */
    @Override
    public Page<MachineRoad> queryByPage(MachineRoad machineRoad, PageRequest pageRequest) {
        long total = this.machineRoadMapper.count(machineRoad);
        return new PageImpl<>(this.machineRoadMapper.queryAllByLimit(machineRoad, pageRequest), pageRequest, total);
    }

    /**
     * 新增数据
     *
     * @param machineRoad 实例对象
     * @return 实例对象
     */
    @Override
    public MachineRoad insert(MachineRoad machineRoad) {
        this.machineRoadMapper.insert(machineRoad);
        return machineRoad;
    }

    /**
     * 修改数据
     *
     * @param machineRoad 实例对象
     * @return 实例对象
     */
    @Override
    public MachineRoad update(MachineRoad machineRoad) {
        this.machineRoadMapper.update(machineRoad);
        return this.queryById(machineRoad.getMachineId());
    }

    /**
     * 通过主键删除数据
     *
     * @param machineId 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(String machineId) {
        return this.machineRoadMapper.deleteById(machineId) > 0;
    }

    @Override
    public MachineComboDetailsDto getComboDetails(String machineId) {

        List<DeviceCurrentComboPlanRoad> deviceCurrentComboPlanRoads = deviceCurrentComboPlanRoadService.getAllByMachineId(machineId);

        if (CollUtil.isEmpty(deviceCurrentComboPlanRoads)) return null;

        List<ComboDetailsDto> comboDetailsDtoList = new ArrayList<>();

        MachineComboDetailsDto machineComboDetailsDto = new MachineComboDetailsDto();

        List<ComboDetailsDto> machineDtoList = deviceCurrentComboPlanRoads.stream()
                .map(road -> {
                    ComboDetailsDto comboDetailsDto = new ComboDetailsDto();
                    comboDetailsDto.setComboId(road.getComboId());
                    comboDetailsDto.setRoadNo(road.getRoadNumber());
                    comboDetailsDto.setMachineId(road.getMachineId());
                    comboDetailsDto.setInventory(Integer.valueOf(road.getComboNum()));
                    return comboDetailsDto;
                }).toList();

        AtomicInteger total = new AtomicInteger();


        //设备套餐总数
        machineDtoList.forEach(comboDetailsDto -> {
            total.addAndGet(comboDetailsDto.getInventory());
        });

        machineComboDetailsDto.setMachineId(machineId);
        machineComboDetailsDto.setTotal(String.valueOf(total));
        machineComboDetailsDto.setComboDetailsDtoList(comboDetailsDtoList);

        return machineComboDetailsDto;
    }

    @Override
    public List<RoadInfoDto> getRoadList(String machineId) {

        List<DeviceCurrentComboPlanRoad> deviceCurrentComboPlanRoads = deviceCurrentComboPlanRoadService.getAllByMachineId(machineId);

        if (CollUtil.isEmpty(deviceCurrentComboPlanRoads)) return Collections.emptyList();

        List<RoadInfoDto> roadInfoDtoList = new ArrayList<>();
        deviceCurrentComboPlanRoads.forEach(machineRoads -> {

            RoadInfoDto roadInfoDto = new RoadInfoDto();
            roadInfoDto.setRoadNo(machineRoads.getRoadNumber());
            roadInfoDto.setId(machineRoads.getId());
            roadInfoDto.setComboId(machineRoads.getComboId());
            roadInfoDto.setOnShelfTime(machineRoads.getCreateTime());
            roadInfoDto.setInventory(machineRoads.getComboNum());


            Combo combo = comboService.queryById(machineRoads.getComboId());
            if (ObjectUtil.isNotNull(combo)) {
                roadInfoDto.setComboName(combo.getName());
                roadInfoDto.setPrice(combo.getSalePrice());

                ImgResource imgResource = imgResourceMapper.queryById(combo.getThumb());
                if (ObjectUtil.isNotNull(imgResource)) {
                    roadInfoDto.setComboImg(imgResource.getUrl());
                }

            }
            roadInfoDtoList.add(roadInfoDto);
        });
        return roadInfoDtoList;
    }

    @Override
    public boolean inventoryModify(List<MachineRoad> machineRoads) {
        this.machineRoadMapper.insertOrUpdateBatch(machineRoads);
        MachineRoad machineRoad = CollUtil.getFirst(machineRoads);
        JSONObject pushObj = new JSONObject();
        pushObj.set(EmqxConstants.TOPIC_PUSH_MSG_TYPE, EmqxConstants.TOPIC_PUSH_ROAD_INVENTORY);
        pushObj.set(EmqxConstants.TOPIC_PUSH_TIME, DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));

        String msgObj = pushObj.toString();
        try {
            matchSendClient.publish(false, machineRoad.getMachineId(), msgObj);
        } catch (MqttException e) {
            log.error("推送设备货道库存更新失败,", e);
            return false;
        }
        return true;
    }
}
